package com.xuanxu.blogs.module.user.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuanxu.blogs.framework.common.exception.MissRequestParameterException;
import com.xuanxu.blogs.module.user.config.AuthProperties;
import com.xuanxu.blogs.module.user.entity.po.User;
import com.xuanxu.blogs.module.user.entity.po.UserToken;
import com.xuanxu.blogs.module.user.entity.vo.app.PasswordLoginRequestVo;
import com.xuanxu.blogs.module.user.exception.UsernameOrPasswordErrorException;
import com.xuanxu.blogs.module.user.mapper.UserMapper;
import com.xuanxu.blogs.module.user.mapper.UserTokenMapper;
import com.xuanxu.blogs.module.user.service.AuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

import static com.xuanxu.blogs.module.user.enums.UserHttpStatusEnum.USERNAME_OR_PASSWORD_ERROR;

/**
 * @author XuanXu
 * @version 1.0
 * @date 2024-08-20 16:26
 */
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final UserMapper userMapper;
    private final UserTokenMapper userTokenMapper;
    private final AuthProperties authProperties;

    @Override
    public String login(PasswordLoginRequestVo passwordLoginRequestVo) {
        if (passwordLoginRequestVo == null) {
            throw new MissRequestParameterException();
        }

        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getUsername, passwordLoginRequestVo.getUsername());
        userLambdaQueryWrapper.eq(User::getPassword, passwordLoginRequestVo.getPassword());
        User user = userMapper.selectOne(userLambdaQueryWrapper);

        if (user == null) {
            throw new UsernameOrPasswordErrorException(USERNAME_OR_PASSWORD_ERROR);
        }

        // 生成 token 并保存到数据库
        String token = IdUtil.simpleUUID() + System.currentTimeMillis();
        LocalDateTime effectiveTime = LocalDateTime.now();
        LocalDateTime expirationTime = effectiveTime.plus(authProperties.getPeriodValidity(), ChronoUnit.SECONDS);

        UserToken userToken = new UserToken();
        userToken.setUserId(user.getUserId());
        userToken.setToken(token);
        userToken.setEffectiveTime(effectiveTime);
        userToken.setPeriodValidity(authProperties.getPeriodValidity());
        userToken.setExpirationTime(expirationTime);

        userTokenMapper.insert(userToken);

        return token;
    }
}
